import os
from platform import machine
import pandas as pd
import toml
from glob import glob
from util import to_snake_mea, get_symbol_group, load_from_db, \
subscribers_path, fast_feed_data_path, raw_feed_data_path, \
to_absolute_week, to_absolute_month, to_absolute_day, to_absolute_quarter


known_issue = {
    # 'Spot.Gdax.v1':['WLUNA-USD', 'UST-USD', 'WLUNA-EUR', 'WLUNA-USDT', 'UST-EUR', 'UST-USDT', 'WLUNA-GBP', 'DAR-USDT'],
}


def get_fastfeed_folder(row):
    with open(subscribers_path, 'r') as f:
        subscribe_config = toml.load(f)
        snake_mea = to_snake_mea(row['mea'])
        mea = row['mea']
        if snake_mea == 'spot_gateio_v4':
            return mea+'.bbo'
        try:
            return mea+'.'+subscribe_config[snake_mea]['default_recipe']
        except Exception:
            return mea+'.realtime'


def print_info(symbols_info:pd.DataFrame, rows, groups=None):

    machine_set = set(symbols_info['machine'])
    for machine in machine_set:
        mea_symbol_dict = dict()
        group_dict = dict()
        for num in rows:
            info = symbols_info.iloc[num]
            if info['machine'] == machine:
                mea = info['mea']
                if mea not in mea_symbol_dict.keys():
                    mea_symbol_dict[mea] = [info['symbol']]
                    if groups is not None:
                        group_dict[mea] = {groups[num]}
                else:
                    mea_symbol_dict[mea].append(info['symbol'])
                    if groups is not None:
                        group_dict[mea].add(groups[num])
        if len(mea_symbol_dict) > 0 :
            print(f"{machine}:")
            for key in mea_symbol_dict.keys():
                print("  %s:" % key)
                print('    ', mea_symbol_dict[key])
                if groups is not None:
                    print('    ', group_dict[key])
            print('')


def to_absolute_symbol(symbol, date):
    next = cal_next(symbol)
    exchange_pair = symbol.split('.')[0]
    if 'DAY' in symbol:
        return exchange_pair+'.'+to_absolute_day(date, next)
    elif 'WEEK' in symbol:
        return exchange_pair+'.'+to_absolute_week(date, next)
    elif 'MONTH' in symbol:
        return exchange_pair+'.'+to_absolute_month(date, next)
    elif 'QUARTER' in symbol:
        return exchange_pair+'.'+to_absolute_quarter(date, next)
    else:
        return symbol


def cal_next(symbol):
    for n in range(4, -1, -1):
        if ('N'*n+'EXT' in symbol):
            return n
    return 0


def check_fast_feed(info, date):
    folder = get_fastfeed_folder(info)
    absnorm_symbol = to_absolute_symbol(info['symbol'], date)
    fast_feed_path = os.path.join(fast_feed_data_path % (
        info['machine'], date, folder), '%s.W0.lz4' % info['symbol'])
    fast_feed_path_absnorm = os.path.join(fast_feed_data_path % (
        info['machine'], date, folder), '%s.W0.lz4' % absnorm_symbol)
    # print(fast_feed_path_absnorm)
    return len(glob(fast_feed_path)) == 0 and len(glob(fast_feed_path_absnorm)) == 0


def check_missing_symbols(date, symbols_info, print_log=True):
    have_fast_feed_data = set()
    no_fast_feed_data = set()
    no_raw_feed_data = set()
    remove_symbol = set()
    no_product_symbol = set()
    no_raw_feed_group = {}
    symbol_groups = get_symbol_group()
    checked_path = dict()
    for row in symbols_info.iterrows():
        rownum = row[0]
        row = row[1]
        # no fast feed file
        if check_fast_feed(row, date):
            if row['mea'] in known_issue.keys() and row['symbol'] in known_issue[row['mea']]:
                no_product_symbol.add(rownum)
            # check raw feed file
            else:
                have_symbol = False
                mea = to_snake_mea(row['mea'])
                for group in symbol_groups[mea]:
                    if row['symbol'] in symbol_groups[mea][group]:
                        have_symbol = True
                        raw_feed_path = os.path.join(raw_feed_data_path % (
                            row['machine'], date, to_snake_mea(row['mea'])), '*_%s[1-2]*' % group)
                        if raw_feed_path not in checked_path.keys():
                            checked_path[raw_feed_path] = len(
                                glob(raw_feed_path))
                        if checked_path[raw_feed_path] == 0:
                            no_raw_feed_data.add(rownum)
                            no_raw_feed_group[rownum] = group
                        break
                if have_symbol is False:
                    remove_symbol.add(rownum)
                else:
                    no_fast_feed_data.add(rownum)
        # have fast feed file
        else:
            have_fast_feed_data.add(rownum)

    if print_log:
        print('-'*15+'Status of Missing Symbols in %s' % date + '-'*15)
        print('')
        if len(no_raw_feed_data) > 0:
            print('-'*15+'WARNING:RAW FEED MISSING'+'-'*15)
            print_info(symbols_info, no_raw_feed_data, no_raw_feed_group)
        if len(have_fast_feed_data) > 0:
            print('-'*15+'fast feed is good'.title()+'-'*15)
            print_info(symbols_info, have_fast_feed_data)
        if len(no_fast_feed_data) > 0:
            print('-'*15+'no fast feed but have raw feed group'.title()+'-'*15)
            print_info(symbols_info, no_fast_feed_data)
        if len(remove_symbol) > 0:
            print('-'*15+'already removed'.title()+'-'*15)
            print_info(symbols_info, remove_symbol)
        if len(no_product_symbol) > 0:
            print('-'*15+'no product or no actual trading'.title()+'-'*15)
            print_info(symbols_info, no_product_symbol)

    return no_fast_feed_data


def main(date):
    check_missing_symbols(date, load_from_db(date))


if __name__ == '__main__':
    main('20230601')
